#ifndef DAPEVENT_HPP
#define DAPEVENT_HPP

#include "dap.hpp"
#include "dap_exports.hpp"

#include <wx/event.h>

class WXDLLIMPEXP_DAP DAPEvent : public wxCommandEvent
{
protected:
    std::shared_ptr<dap::Any> m_object;
    std::shared_ptr<dap::Request>
        m_originatingRequest; // for events that holds a response, this pointer will contain the originating request

public:
    DAPEvent(wxEventType commandType = wxEVT_NULL, int winid = 0);
    DAPEvent(const DAPEvent& event);
    DAPEvent& operator=(const DAPEvent& src);
    virtual ~DAPEvent();

    void SetAnyObject(std::shared_ptr<dap::Any> any) { m_object = any; }
    void SetOriginatingRequest(std::shared_ptr<dap::Request> req) { m_originatingRequest = req; }
    std::shared_ptr<dap::Request> GetOriginatingRequest() { return m_originatingRequest; }

    wxEvent* Clone() const override;
    dap::Event* GetDapEvent() const;
    dap::Response* GetDapResponse() const;
    dap::Request* GetDapRequest() const;
};

typedef void (wxEvtHandler::*DAPEventFunction)(DAPEvent&);
#define DAPEventHandler(func) wxEVENT_HANDLER_CAST(DAPEventFunction, func)

wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_LOG_EVENT, DAPEvent);

wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_LOST_CONNECTION, DAPEvent);

wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_INITIALIZE_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_STACKTRACE_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_SCOPES_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_VARIABLES_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_SET_SOURCE_BREAKPOINT_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_SET_FUNCTION_BREAKPOINT_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_BREAKPOINT_LOCATIONS_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_CONFIGURARIONE_DONE_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_LAUNCH_RESPONSE, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_THREADS_RESPONSE, DAPEvent);

wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_RUN_IN_TERMINAL_REQUEST, DAPEvent);

wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_STOPPED_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_STOPPED_ON_ENTRY_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_PROCESS_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_EXITED_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_TERMINATED_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_INITIALIZED_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_OUTPUT_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_BREAKPOINT_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_CONTINUED_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_MODULE_EVENT, DAPEvent);
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_DAP, wxEVT_DAP_DEBUGPYWAITINGFORSERVER_EVENT, DAPEvent);

#endif // DAPEVENT_HPP
